package com.nfit.shopweb.Interceptor;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.nfit.shopcommon.utils.ThreadLocalUtil;
import com.nfit.shopmodel.entity.system.SysUser;
import com.nfit.shopmodel.vo.common.AuthConst;
import com.nfit.shopmodel.vo.common.Result;
import com.nfit.shopmodel.vo.common.ResultCodeEnum;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;

import static com.nfit.shopmodel.vo.common.AuthConst.THREADLOCAL_API_USER;

/**
 * ClassName:LoginInterceptor
 * Package:com.nfit.shopweb.Interceptor
 * Description
 *
 * @Author L
 * @Create 2024/11/15 19:05
 */
@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //放行预检检查
        if ("OPTIONS".equals(request.getMethod())) {
            return true;
        }

        //获取请求头token
        String token = request.getHeader("token");

        //为空,终止
        if (StrUtil.isBlank(token)) {
            responseNoLoginInfo(response);
            return false;
        }

        //从redis中获取登入用户数据
        String redisUser = redisTemplate.opsForValue().get(AuthConst.LOGIN_USER+token);
        //为空终止
        if (StrUtil.isBlank(redisUser)) {
            responseNoLoginInfo(response);
            return false;
        }

        //存入线程中
        ThreadLocalUtil.set(THREADLOCAL_API_USER,JSON.parseObject(redisUser, SysUser.class));

        SysUser sysUser = ThreadLocalUtil.get(THREADLOCAL_API_USER);
        log.info("获取存入线程的数据：{}",sysUser);

        //更新redis中的数据过期时间
        redisTemplate.expire(AuthConst.LOGIN_USER+token,30, TimeUnit.MINUTES);

        return true;
    }

    /**
     * 封装好异常消息状态码
     * @param response
     */
    //响应208状态码给前端
    private void responseNoLoginInfo(HttpServletResponse response) {
        //统一格式异常消息
        Result<Object> result = Result.build(null, ResultCodeEnum.LOGIN_AUTH);
        //初始化输出流
        PrintWriter writer = null;
        //设置编码格式
        response.setCharacterEncoding("UTF-8");
//        response.setContentType("text/html; charset=utf-8");
        try {
            //获取输出流
            writer = response.getWriter();
            //响应给前端
            writer.print(JSON.toJSONString(result));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //不等于null,关闭流,等于null,不需要关闭流
            if (writer != null) writer.close();
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        ThreadLocalUtil.remove(THREADLOCAL_API_USER);
    }
}
